package masterjava.common.settings;

import masterjava.common.convertion.GenericStringConverter;
import masterjava.common.convertion.SimpleStringConverter;
import masterjava.common.shared.Convertible;
import masterjava.common.store.FileStore;
import masterjava.common.store.IPropertiesStore;
import masterjava.common.store.IPropertyListener;
import masterjava.common.store.Property;
import org.jetbrains.annotations.Nullable;

import java.io.File;

/**
 * MasterJava.ru
 * <p/>
 * User: GKislin
 * Date: 03.03.11
 * <p/>
 * Factory for properties, based on IPropertiesStore
 *
 * @see IPropertiesStore
 */
public class PropsFactory {
    protected IPropertiesStore propStore;

    public PropsFactory(IPropertiesStore propStore) {
        this.propStore = propStore;
    }

    public Property<String> create(Enum key) throws IllegalArgumentException {
        return create(key.name(), null, SimpleStringConverter.get());
    }

    public <T> Property<T> create(Enum key, Class<T> clazz) throws IllegalArgumentException {
        return create(key.name(), null, clazz);
    }

    public <T> Property<T> create(Enum key, T defValue) throws IllegalArgumentException {
        return create(key.name(), defValue);
    }

    public <T> Property<T> create(String key, Class<T> clazz) throws IllegalArgumentException {
        return create(key, null, clazz);
    }

    @SuppressWarnings("unchecked")
    public <T> Property<T> create(String key, T defValue) throws IllegalArgumentException {
        return create(key, defValue, (Class<T>) defValue.getClass());
    }

    public <T> Property<T> create(String key, @Nullable T defValue, Class<T> clazz) throws IllegalArgumentException {
        return create(key, defValue, new GenericStringConverter<T>(clazz));
    }

    public <T> Property<T> create(Enum key, Convertible<T> converter) throws IllegalArgumentException {
        return create(key.name(), null, converter);
    }

    public <T> Property<T> create(String key, @Nullable T defValue, Convertible<T> converter) throws IllegalArgumentException {
        return create(key, defValue, converter, propStore);
    }

    public Property<String> createFieStore(Enum key, Property<File> propFile) throws IllegalArgumentException {
        final Property<String> prop = create(key.name(), null, SimpleStringConverter.get(), new FileStore(propFile));
        propFile.addListener(new IPropertyListener<File>() {
            @Override
            public void update(Property<File> newProp, File oldValue) {
                prop.reInitValue();
            }
        });
        return prop;
    }

    public <T> Property<T> create(String key, @Nullable T defValue, Convertible<T> converter, IPropertiesStore propStore) throws IllegalArgumentException {
        Property<T> prop = new Property<T>(key, defValue, converter, propStore);
        propStore.addConfigurationListener(prop);
        return prop;
    }
}
